﻿#include "once_trigger_thread.h"
// #include "daq_ipc/logger/logger.h"

void OnceTriggerADCThread::start(Priority priority) {
  thread_is_running_ = true;
  QThread::start(priority);

  total_data_length_ = base_device_.toStrongRef()->GetCurrentDataLength();
  data_.resize(base_device_.toStrongRef()->GetADCLegalChannelSize());
  for (int i = 0; i < data_.size(); i++) {
    data_[i].reserve(2 * total_data_length_);
  }

  // 超时时间 = 数据长度 / 采样率
  timeout_msec_ = (static_cast<double>(total_data_length_) / base_device_.toStrongRef()->GetCurrentSampleRate() * 1000) + 500;
}

void OnceTriggerADCThread::quit() {
  thread_is_running_ = false;
  QThread::wait();
  QThread::quit();
}

void OnceTriggerADCThread::run() {
    qInfo(u8"线程开启");
  const auto base_device = base_device_.toStrongRef();

  // 上次读取数据的时间
  auto buffer_data_time_last = std::chrono::steady_clock::now();

  while (thread_is_running_) {
    bool success = ReadADCData();

    if (success) {
      buffer_data_time_last = std::chrono::steady_clock::now();
    } else if (!CheckDataEmpty() &&
               CheckTimeout(buffer_data_time_last, timeout_msec_)) {
      // 超时默认后面没有数据 发送数据
      emit SendData(data_);
      for (auto &i: data_) {
        i.clear();
      }
      break;
    }
  }
  qInfo(u8"线程结束");
}

bool OnceTriggerADCThread::ReadADCData() {
  int success = false;
  const auto base_device = base_device_.toStrongRef();
  const auto channel_number = base_device->GetADCLegalChannel().size();
  for (int i = 0; i < channel_number; i++) {
    float temp_data = 0;
    if (!base_device->TryReadADCData(i, &temp_data)) {
      continue;
    }

    data_[i].emplace_back(temp_data);
    success = true;
  }

  return success;
}

bool OnceTriggerADCThread::CheckTimeout(const std::chrono::steady_clock::time_point &start, const int timeout_msec) {
  auto diff = std::chrono::steady_clock::now() - start;
  auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(diff);

  if (duration.count() >= timeout_msec) {
    // 超时
    return true;
  }

  return false;
}

bool OnceTriggerADCThread::CheckDataEmpty() {
  for (auto &i: data_) {
    if (!i.empty()) {
      return false;
    }
  }

  return true;
}
